#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <sched.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include "modbus_client.h"
#include "common.h"

// 新增TCP缓冲区设置函数
int set_tcp_buffer_size(modbus_t* ctx, uint32_t send_size, uint32_t recv_size) {
    int socket = modbus_get_socket(ctx);
    if (socket == -1) return -1;
    
    // 设置发送缓冲区
    if (setsockopt(socket, SOL_SOCKET, SO_SNDBUF, &send_size, sizeof(send_size)) == -1) {
        perror("Warning: Failed to set TCP send buffer size");
        return -1;
    }
    
    // 设置接收缓冲区
    if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &recv_size, sizeof(recv_size)) == -1) {
        perror("Warning: Failed to set TCP recv buffer size");
        return -1;
    }
    
    printf("TCP buffers set: send=%d, recv=%d\n", send_size, recv_size);
    return 0;
}

// 禁用TCP延迟确认
int set_tcp_quickack(modbus_t* ctx, bool enable) {
    int socket = modbus_get_socket(ctx);
    if (socket == -1) return -1;
    
    int flag = enable ? 1 : 0;
    if (setsockopt(socket, IPPROTO_TCP, TCP_QUICKACK, &flag, sizeof(flag)) == -1) {
        perror("Warning: Failed to set TCP_QUICKACK");
        return -1;
    }
    
    printf("TCP quick ACK %s\n", enable ? "enabled" : "disabled");
    return 0;
}

// 禁用Nagle算法（原有函数，保持不变）
int set_tcp_nodelay(modbus_t* ctx, bool enable) {
    int socket = modbus_get_socket(ctx);
    if (socket == -1) return -1;
    
    int flag = enable ? 1 : 0;
    return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
}

int modbus_client_init(modbus_client_t *client, const config_t *config, uint8_t link_id) {
    memset(client, 0, sizeof(modbus_client_t));
    client->config = *config;
    client->link_id = link_id;
    client->running = true;

    // 使用对应链路的服务器配置
    const char* ip = config->modbus_servers[link_id].ip;
    uint32_t port = config->modbus_servers[link_id].port;
    uint32_t slave_id = config->modbus_servers[link_id].slave_id;

    // 创建Modbus上下文
    client->ctx = modbus_new_tcp(ip, port);
    if (client->ctx == NULL) {
        fprintf(stderr, "Error: Unable to create Modbus context for link %d\n",link_id);
        return -1;
    }

    // 设置从站ID
    modbus_set_slave(client->ctx, slave_id);
    
    // 设置超时
    modbus_set_response_timeout(client->ctx, 1, 0);  // 1秒响应超时
    modbus_set_byte_timeout(client->ctx, 0, 100000); // 100ms字节超时

    // 连接服务器
    if (modbus_connect(client->ctx) == -1) {
        fprintf(stderr, "Error: Connection failed for link %d: %s\n",link_id, modbus_strerror(errno));
        modbus_free(client->ctx);
        client->ctx = NULL;
        return -1;
    }

    // TCP优化设置
    printf("Applying TCP optimizations...\n");

    const rt_config_t* rt_cfg = &config->rt_configs[link_id];
    
    // 1. 禁用Nagle算法
    if (config->modbus_servers[link_id].disable_nagle) {
        if (set_tcp_nodelay(client->ctx, true) != 0) {
            fprintf(stderr, "Warning: Failed to disable Nagle algorithm\n");
        } else {
            printf("Nagle algorithm disabled\n");
        }
    }
    
    // 2. 设置TCP缓冲区大小
    if (set_tcp_buffer_size(client->ctx, 
                           rt_cfg->tcp_send_buffer_size,
                           rt_cfg->tcp_recv_buffer_size) != 0) {
        fprintf(stderr, "Warning: Failed to set TCP buffer sizes\n");
    }
    
    // 3. 禁用TCP延迟确认
    if (rt_cfg->disable_tcp_delay_ack) {
        if (set_tcp_quickack(client->ctx, true) != 0) {
            fprintf(stderr, "Warning: Failed to disable TCP delay ACK\n");
        }
    }

    printf("[Link %d]Connected to Modbus server %s:%d (Slave ID: %d)\n", 
            client->link_id,
            config->modbus_servers[client->link_id].ip, 
            config->modbus_servers[client->link_id].port, 
            config->modbus_servers[client->link_id].slave_id);

    return 0;
}

void modbus_client_cleanup(modbus_client_t *client) {
    if (client->ctx) {
        modbus_close(client->ctx);
        modbus_free(client->ctx);
        client->ctx = NULL;
    }
}

// 使用修正后的函数名
void* modbus_client_thread(void* arg) {
    modbus_client_t* client = (modbus_client_t*)arg;

    printf("Pressure test started - Polling interval: %dms\n", 
           client->config.polling_interval_ms);
    printf("Register range: %d-%d (%d registers per operation)\n",
           client->config.holding_register_range.start_address,
           client->config.holding_register_range.end_address,
           REGISTER_COUNT);

    // 初始化周期定时器
    uint64_t target_interval_ns = client->config.polling_interval_ms * 1000000ULL;
    init_periodic_timer(&client->timer, target_interval_ns);

    // 预热连接
    printf("Warming up connection...\n");
    uint16_t test_reg[1];
    for (int i = 0; i < 10 && client->running; i++) {
        if (modbus_read_registers(client->ctx, 0, 1, test_reg) == 1) {
            printf("Warmup %d: OK\n", i + 1);
        } else {
            printf("Warmup %d: Failed\n", i + 1);
        }
        usleep(100000); // 100ms间隔
    }
    printf("Warmup completed\n");

    // 执行压力测试
    execute_pressure_test(client);

    // 清理资源

    printf("Pressure test thread exiting\n");
    
    return NULL;
}
